package com.item.mobile;

import static com.base.util.StringUtil.emptyIfBlank;
import static com.item.mobile.MobileUtil.checkParam;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.base.dialect.PaginationSupport;
import com.base.mobile.MobException;
import com.base.mobile.MobileInfo;
import com.base.mobile.server.annotation.Mobile;
import com.base.mobile.server.annotation.MobileMethod;
import com.base.service.BFileService;
import com.base.util.DateUtil;
import com.base.util.StringUtil;
import com.item.dao.model.Question;
import com.item.dao.model.QuestionExample;
import com.item.dao.model.QuestionRecommend;
import com.item.dao.model.QuestionRecommendExample;
import com.item.dao.model.User;
import com.item.service.QuestionRecommendService;
import com.item.service.QuestionService;
import com.item.service.SignService;
import com.item.service.UserService;
import com.item.util.ConstantResources;
import com.item.util.MailUtil;
import com.item.util.MyDateUtils;
import com.item.util.SubjectUtils;
import com.mobile.api.proto.MAppIndex.MDateList;
import com.mobile.api.proto.MAppQuestion.MQuestion;
import com.mobile.api.proto.MAppQuestion.MQuestionCount;
import com.mobile.api.proto.MAppQuestion.MQuestions;
import com.mobile.api.proto.MSystem.MRet;

@Component
@Mobile
public class MAppQuestion {
	@Autowired
	private QuestionService questionService;
	@Autowired
	private UserService userService;
	@Autowired
	private QuestionRecommendService recommendService;
	@Autowired
	private SignService signService;
	@Autowired
	private  BFileService fileService;
	
	private static HashMap<String, List<QuestionRecommend>> recommendCache =
			new HashMap<String, List<QuestionRecommend>>();
	public static String[] SUBJECTS = 
		{"英语一", "英语二", "英语三", "政治", "数学一", "数学二", "数学三", "专业课一", "专业课二"};
	
	@MobileMethod(methodno = "MUpdateSubject", isLogin = true)
	public MRet.Builder updateSubject(MobileInfo mobileInfo,
			String subjectEng, String subjectMath,
			String subjectMajor1, String subjectMajor2) throws Exception {
		MRet.Builder ret = MRet.newBuilder();
		
//		checkParam(subjectEng, "subjectEng");
//		checkParam(subjectMath, "subjectMath");
//		checkParam(subjectMajor1, "subjectMajor1");	
//		checkParam(subjectMajor2, "subjectMajor2");		
		
				
		User user = new User();
		user.setId(mobileInfo.getUserid());
		user.setSubjectMajor1(StringUtil.emptyIfBlank(subjectMajor1));
		user.setSubjectMajor2(StringUtil.emptyIfBlank(subjectMajor2));
		user.setSubjectEng(StringUtil.emptyIfBlank(subjectEng));
		user.setSubjectMath(StringUtil.emptyIfBlank(subjectMath));
		if(userService.updateByPrimaryKeySelective(user) > 0)
			ret.setCode(1);
		return ret;
	}
	
	@MobileMethod(methodno = "MUploadQues", isLogin = true)
	public MRet.Builder uploadQues( 
			Question question) throws Exception  {
		MRet.Builder ret = MRet.newBuilder();
		
		checkParam(question.getId(), "id");
		checkParam(question.getImg(), "img");
		checkParam(question.getCreateTime(), "createTime");
		checkParam(question.getSubject(), "subject");
		checkParam(question.getType(), "type");
		checkParam(question.getIsHighlight(), "isHighlight");
		checkParam(question.getIsRecommend(), "isRecommend");
		checkParam(question.getHasLearned(), "hasLearned");
		checkParam(question.getReviewCount(), "reviewCount");
		
		question.setUploadTime(new Date(System.currentTimeMillis()));
		if(question.getStatus() == null){
			question.setStatus(1);
		}
		if(questionService.selectByPrimaryKey(question.getId()) == null) {
			if(questionService.insertSelective(question) > 0)
				ret.setCode(1);
		} else {
			//记录下第一次复习的实际那
			Question qtemp = questionService.selectByPrimaryKey(question.getId());
				//表示这是第一次复习的时间，可以用来统计已复习的数目
			if(qtemp.getHasLearned() == 0 && question.getHasLearned() == 1){
				question.setLastTime(new Date());
			}
			question.setModifyTime(new Date());
			if(questionService.updateByPrimaryKeySelective(question) > 0)
				ret.setCode(1);
		}
		return ret;
	}
	
	@MobileMethod(methodno = "MQuesCountStatus", isLogin = true) 
	public MQuestionCount.Builder questionCount(MobileInfo mobileInfo,String date) throws Exception {
		if(date == null){
			date = MyDateUtils.parseDateWithDay(new Date());
		}
		MQuestionCount.Builder ret = count(mobileInfo,date,false);
		return ret;
	}
	
	@MobileMethod(methodno = "MQuesCountStatusAll", isLogin = true) 
	public MQuestionCount.Builder questionCountAll(MobileInfo mobileInfo,String date) throws Exception {
		if(date == null){
			date = MyDateUtils.parseDateWithDay(new Date());
		}
		MQuestionCount.Builder ret = count(mobileInfo,date,true);
		return ret;
	}
	
	
	public MQuestionCount.Builder count(MobileInfo mobileInfo,String date,boolean all){
		MQuestionCount.Builder ret = MQuestionCount.newBuilder();
		
		int tCount = 0, temp = 0;
		
		QuestionExample example = new QuestionExample();
		//math
		QuestionExample.Criteria crMath = example.createCriteria();
		crMath.andUseridEqualTo(mobileInfo.getUserid())
		.andTypeEqualTo(3);
		if(!all){
			crMath.andStatusEqualTo(1);
		}
		temp = questionService.countByExample(example);
		tCount += temp;
		ret.setMathCount(temp);
		
		//eng
		example.clear();
		QuestionExample.Criteria crEng = example.createCriteria();
		crEng.andUseridEqualTo(mobileInfo.getUserid())
		.andTypeEqualTo(1);
		if(!all){
			crEng.andStatusEqualTo(1);
		}
		temp = questionService.countByExample(example);
		tCount += temp;
		ret.setEngCount(temp);
		
		//polity
		example.clear();
		QuestionExample.Criteria crPolity = example.createCriteria();
		crPolity.andUseridEqualTo(mobileInfo.getUserid())
		.andTypeEqualTo(2);
		if(!all){
			crPolity.andStatusEqualTo(1);
		}
		temp = questionService.countByExample(example);
		tCount += temp;
		ret.setPolityCount(temp);
		
		//m1
		example.clear();
		QuestionExample.Criteria crM1 = example.createCriteria();
		crM1.andUseridEqualTo(mobileInfo.getUserid())
		.andTypeEqualTo(4);
		if(!all){
			crM1.andStatusEqualTo(1);
		}
		temp = questionService.countByExample(example);
		tCount += temp;
		ret.setMajor1Count(temp);
		
		//m2
		example.clear();
		QuestionExample.Criteria crM2 = example.createCriteria();
		crM2.andUseridEqualTo(mobileInfo.getUserid())
		.andTypeEqualTo(5);
		if(!all){
			crM2.andStatusEqualTo(1);
		}
		temp = questionService.countByExample(example);
		tCount += temp;
		ret.setMajor2Count(temp);
		
		ret.setTotoalCount(tCount);
		
		//再去获取新增的题目数量
		Map<String,String> map = new HashMap<String, String>();
        map.put("userid", mobileInfo.getUserid());
        map.put("date", date);
        if(all){
        	map.put("all", "all");
        }
        Map<String,Long> result = questionService.getNewAddedQuestionCount(map);
        ret.setEngAddedCount(result.get("engCount").intValue());
		ret.setMathAddedCount(result.get("mathCount").intValue());
		ret.setPolityAddedCount(result.get("polityCount").intValue());
		ret.setMajor1AddedCount(result.get("major1Count").intValue());
		ret.setMajor2AddedCount(result.get("major2Count").intValue());
		return ret;
	}
	
	
	
	@MobileMethod(methodno = "MQuesList", isLogin = true) 
	public MQuestions.Builder queslist(MobileInfo mobileInfo,
			Date date, Integer type) throws Exception {
		checkParam(date, "date");
		date = DateUtil.getDate(
				DateUtil.getYear(date),
				DateUtil.getMonth(date), 
				DateUtil.getDay(date));
//		PaginationSupport.setContext(page, limit, null);
		MQuestions.Builder ret = list(mobileInfo,date,type,false);
		return ret;
	}
	
	@MobileMethod(methodno = "MQuesListAll", isLogin = true) 
	public MQuestions.Builder queslistAll(MobileInfo mobileInfo,
			Date date, Integer type) throws Exception {
		checkParam(date, "date");
		date = DateUtil.getDate(
				DateUtil.getYear(date),
				DateUtil.getMonth(date), 
				DateUtil.getDay(date));
//		PaginationSupport.setContext(page, limit, null);
		MQuestions.Builder ret = list(mobileInfo,date,type,true);
		return ret;
	}
	

	public MQuestions.Builder list(MobileInfo mobileInfo, Date date, Integer type,boolean all){
		MQuestions.Builder ret = MQuestions.newBuilder();
		QuestionExample example = 
				new QuestionExample();
		//XXX confirm the edge time
		QuestionExample.Criteria criteria = 
				example.createCriteria();
		criteria.andCreateTimeGreaterThanOrEqualTo(date)
				.andCreateTimeLessThan(DateUtil.add(date, 1))
				.andUseridEqualTo(mobileInfo.getUserid()); //1: not deleted
		if(!all){
			criteria.andStatusEqualTo(1);
		}
		if(type != null) {
			criteria.andTypeEqualTo(type);
		}
		List<Question> list = questionService.selectByExample(example);
		for(Question q : list) {
			ret.addList(assembleData(q));
		}
		
		return ret;
	}
	
	@MobileMethod(methodno = "MQuesPrint", isLogin = true)
	public MRet.Builder quesPrint(MobileInfo mobileInfo, 
			Date startDate, Date endDate, Integer type) throws Exception {
		MRet.Builder ret = MRet.newBuilder();
		
		checkParam(startDate, "startDate");
		checkParam(endDate, "endDate");
		checkParam(type, "type");
		User user = userService.selectByPrimaryKey(mobileInfo.getUserid());
		if(StringUtils.isBlank(user.getEmail())){
			throw new MobException(MEnumError.EMAIL_EMPTY_ERROR);
		}
		String start = MyDateUtils.parseDateWithDay(startDate);
		String end = MyDateUtils.parseDateWithDay(endDate);
		String emailContent = String.format(ConstantResources.PRINTEMAILCONTENT, SubjectUtils.getSubjectByType(type),start,end, ConstantResources.PRINTURL,mobileInfo.getUserid(),type,start,end,SubjectUtils.getSubjectByType(type));
	
//		System.out.println(file.getFilePath());
		if(MailUtil.sendMail(user.getEmail(), String.format("%s：%s-%s打印链接", SubjectUtils.getSubjectByType(type),start,end), emailContent)){
			ret.setCode(1);
			ret.setMsg("发送成功");
		}else{
			ret.setCode(0);
		}
		return ret;
	}

	@MobileMethod(methodno = "MQuesDelete", isLogin = true)
	public MRet.Builder quesDelete(MobileInfo mobileInfo, String id,
			String userid) throws Exception {
		MRet.Builder ret = MRet.newBuilder();
		
		boolean success = true;
		
		checkParam(id, "id");
		
		QuestionExample example = new QuestionExample();
		Question q = new Question();
		q.setStatus(0); //0: delete
		String[] ids = id.split(",");
		for(String i : ids) {
			example.clear();
			example.createCriteria().andIdEqualTo(i).
			andUseridEqualTo(mobileInfo.getUserid());
			if(questionService.updateByExampleSelective(q, example) < 1)
				success = false;
		}
		
		if(success)
			ret.setCode(1);

		return ret;
	}
	
	@MobileMethod(methodno = "MQuesRecommend", isLogin = false)
	public MQuestions.Builder quesRecommend(MobileInfo mobileInfo, Date date) throws Exception {
		MQuestions.Builder ret = MQuestions.newBuilder();
		User user = null;
		if(ConstantResources.ISDEBUG)
			date = DateUtil.strToDate("2015-03-23", "yyyy-MM-dd");
//		if(date == null) {	
//			date = new Date(System.currentTimeMillis());
//			if(ConstantResources.ISDEBUG)
//				date = DateUtil.strToDate("2015-01-31", "yyyy-MM-dd");
//		}
//		
		boolean defaultRecommend = true;
		//首先添加政治的
	    addRecommendQues(getRecommendCache(SUBJECTS[3], date), ret);

		
		
		if(StringUtils.isNotBlank(mobileInfo.getUserid())) {
			user = userService.selectByPrimaryKey(mobileInfo.getUserid());
			//user has subject info
			if(StringUtils.isNotBlank(user.getSubjectEng()) ||
					StringUtils.isNotBlank(user.getSubjectMath())) {
				defaultRecommend = false;
				addRecommendQues(getRecommendCache(user.getSubjectEng(), date), ret);
				addRecommendQues(getRecommendCache(user.getSubjectMath(), date), ret);
			}
		}
		if(defaultRecommend) {
			addRecommendQues(getRecommendCache(SUBJECTS[0], date), ret);
		}
		return ret;
	}
	
	@MobileMethod(methodno = "MGetDateList", isLogin = true)
	public MDateList.Builder getDateList(MobileInfo mobileInfo,Integer type){
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("userid", mobileInfo.getUserid());
		if(type != null){
			map.put("type", type);
		}
		List<String> dates = questionService.getUploadDateList(map);
		MDateList.Builder ret = MDateList.newBuilder();
		for(String str : dates){
			ret.addDate(str);
		}
		return ret;
	}
	


	public static MQuestion.Builder assembleData(Question question) {
		MQuestion.Builder ret = null;
		
		if(question != null) {
			ret = MQuestion.newBuilder();
			ret.setCreateTime(question.getCreateTime() == null ? "" :
				DateUtil.dateToStr(question.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
			ret.setDisplayName(question.getDisplayName());
			ret.setId(emptyIfBlank(question.getId()));
			ret.setImg(emptyIfBlank(question.getImg()));
			ret.setIsHighlight(question.getIsHighlight() == null ? 0 :
				question.getIsHighlight());
			ret.setIsRecommend(question.getIsRecommend() == null ? 0 : 
				question.getIsRecommend());
			ret.setLastTime(question.getLastTime() == null ? "" :
				DateUtil.dateToStr(question.getLastTime(), "yyyy-MM-dd HH:mm:ss"));
			ret.setRemark(emptyIfBlank(question.getRemark()));
			ret.setSubject(emptyIfBlank(question.getSubject()));
			ret.setType(question.getType() == null ? 0 : question.getType());
			ret.setUserid(emptyIfBlank(question.getUserid()));
			ret.setHasLearned(question.getHasLearned() == null ? 0 : question.getHasLearned());
			ret.setReviewCount(question.getReviewCount() == null ? 0 : question.getReviewCount());
			ret.setStatus(question.getStatus() == null ? 1 : question.getStatus());
		}
		
		return ret;
	}
	
	public MQuestion.Builder assembleData(QuestionRecommend question) {
		MQuestion.Builder ret = null;
		if(question != null) {
			ret = MQuestion.newBuilder();
			ret.setCreateTime(question.getCreateTime() == null ? "" :
				DateUtil.dateToStr(question.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
			ret.setId(emptyIfBlank(question.getId()));
			ret.setImg(question.getImg());
//			ret.setImg(ConstantResources.OSS_BASE_URL_FRAME + fileService.selectByPrimaryKey(question.getImg()).getFilePath());
			ret.setRemark(emptyIfBlank(question.getRemark()));
			ret.setSubject(emptyIfBlank(question.getSubject()));
			ret.setType(question.getType() == null ? 0 : question.getType());
			ret.setIsAd(question.getIsAd() == null ? 0 : question.getIsAd());
			ret.setTitle(StringUtil.emptyIfBlank(question.getTitle()));
		}
		
		return ret;
	}
	
	
	private List<QuestionRecommend> getRecommendCache(String key, Date date) {
		String dateKey = DateUtil.dateToStr(date, "yyyy-MM-dd");
		if(recommendCache.get(dateKey) == null) {
			recommendCache.clear();
			//recommendCache.put(dateKey, new QuestionRecommend());
			QuestionRecommendExample example = new QuestionRecommendExample();
			example.createCriteria().andTimeEqualTo(date).andIsAdEqualTo(0);
			
			List<QuestionRecommend> list = 
					recommendService.selectByExample(example);
			
			for(QuestionRecommend qr : list) {
				if(recommendCache.get(qr.getSubject()) == null){
					List<QuestionRecommend> temp = new ArrayList<QuestionRecommend>();
					temp.add(qr);
					recommendCache.put(qr.getSubject(), temp);
				}else{
					recommendCache.get(qr.getSubject()).add(qr);
				}
			}
			//add ad
			example.clear();
			example.createCriteria().andTimeEqualTo(date).andIsAdEqualTo(1);
			example.setOrderByClause("create_time DESC");
			PaginationSupport.setContext(1, 20, null);
			list = recommendService.selectByExample(example);
			if(list.size() > 0) {
				//recommendCache.put("ad", list.get(0));
			}
		}
		//TODO just for test, delete this later
		//recommendCache.put(dateKey, null);
		return recommendCache.get(key);
	}
	
	private void addRecommendQues(List<QuestionRecommend> list,MQuestions.Builder ret) {
		if(list != null){
			for(QuestionRecommend qr : list){
				ret.addList(assembleData(qr));
			}
		}
	}
}
